﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using BlueMarineWindowsFormsClient.ManagerService;
using Timer = System.Windows.Forms.Timer;

namespace BlueMarineWindowsFormsClient
{
    public partial class frmEmployeeManager : Form
    {
        private readonly List<TextBox> _ctrl;
        private readonly ImageTool _imageTool = new ImageTool();
        private readonly Timer _myTimer;
        private readonly frmMain _parent;
        private readonly Status _status;
        private ManagerServiceClient _employee;

        public frmEmployeeManager(frmMain p)
        {
            InitializeComponent();

            _parent = p;
            _status = new Status(lblStatus);
            InitServiceClient();
            _ctrl = new List<TextBox> {txtName, txtPhone, txtEmail, txtAddress, txtCity, txtCountry};
            cbxJobTitle.SelectedIndex = 0;
            cbxPosition.SelectedIndex = 0;
            _myTimer = new Timer {Interval = 1000};
            _myTimer.Tick += refreshEmpList;
        }

        private void InitServiceClient()
        {
            _employee = new ManagerServiceClient("WSHttpBinding_IManagerService")
                            {
                                ClientCredentials =
                                    {
                                        UserName = {UserName = _parent.UName, Password = _parent.PWord},
                                        ServiceCertificate =
                                            {
                                                Authentication =
                                                    {CertificateValidationMode = X509CertificateValidationMode.None}
                                            }
                                    }
                            };
        }

        private void AbortServiceClient()
        {
            if (_employee.State == CommunicationState.Faulted)
            {
                _employee.Abort();
                InitServiceClient();
            }
        }


        private void btnNew_Click(object sender, EventArgs e)
        {
            if (btnNew.Text == "New")
            {
                foreach (TextBox textBox in _ctrl)
                {
                    textBox.Clear();
                    textBox.Enabled = true;
                }
                cbxJobTitle.Enabled = true;
                cbxPosition.Enabled = true;
                dtpBirthday.Enabled = true;
                btnCreate.Enabled = true;
                btnUpdate.Enabled = false;
                btnDeactive.Enabled = false;
                btnGetAll.Enabled = true;
                txtUserName.Clear();
                txtPassword.Clear();
                btnNew.Text = "Cancel";
            }
            else
            {
                foreach (TextBox textBox in _ctrl)
                {
                    textBox.Clear();
                    textBox.Enabled = false;
                }
                cbxJobTitle.Enabled = false;
                cbxPosition.Enabled = false;
                txtName.Enabled = false;
                dtpBirthday.Enabled = false;
                btnCreate.Enabled = false;
                btnUpdate.Enabled = false;
                btnDeactive.Enabled = false;
                btnGetAll.Enabled = true;
                btnNew.Text = "New";
            }

            errorProvider.Clear();
        }

        private void btnCreate_Click(object sender, EventArgs e)
        {
            try
            {
                _status.STATUS("Writting Employee..");
                if (ValidForm())
                {
                    byte[] image = _imageTool.ImageToByte(ptbEmpImage.Image);
                    if (_employee.EmployeeAdd(txtName.Text, rdbMale.Checked, dtpBirthday.Value,
                                              cbxPosition.SelectedItem.ToString(), txtPhone.Text,
                                              txtEmail.Text, txtAddress.Text, txtCity.Text, txtCountry.Text,
                                              cbxJobTitle.SelectedItem.ToString(), image))
                    {
                        _status.SUCCESS("Create Employee");
                        foreach (TextBox textBox in _ctrl)
                        {
                            textBox.Clear();
                            textBox.Enabled = false;
                        }

                        cbxJobTitle.Enabled = false;
                        cbxPosition.Enabled = false;
                        dtpBirthday.Enabled = false;
                        btnCreate.Enabled = false;
                        btnUpdate.Enabled = false;
                        btnDeactive.Enabled = false;
                        btnGetAll.Enabled = true;
                        btnNew.Text = "New";
                        refresh();
                        return;
                    }
                    _status.FAIL("Create Employee");
                    return;
                }
                _status.ERROR("Invalid input data");
            }
            catch (Exception ex)
            {
                AbortServiceClient();
                _status.ERROR(ex.Message);
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            try
            {
                _status.STATUS("Updating Employee..");
                byte[] image = _imageTool.ImageToByte(ptbEmpImage.Image);
                if (_employee.EmployeeModify(int.Parse(txtId.Text), txtName.Text, rdbMale.Checked, dtpBirthday.Value,
                                             cbxPosition.SelectedItem.ToString(), txtPhone.Text, txtEmail.Text,
                                             txtAddress.Text, txtCity.Text, txtCountry.Text,
                                             cbxJobTitle.SelectedItem.ToString(), image))
                {
                    _status.SUCCESS("Update Employee");
                    btnCreate.Enabled = false;
                    btnUpdate.Enabled = false;
                    btnDeactive.Enabled = false;
                    refresh();
                    return;
                }
                _status.FAIL("Update Employee");
            }

            catch (Exception ex)
            {
                AbortServiceClient();
                _status.ERROR(ex.Message);
            }
        }

        private void btnDeactive_Click(object sender, EventArgs e)
        {
            try
            {
                if (_employee.EmployeeDeactive(int.Parse(txtId.Text)))
                {
                    _status.SUCCESS("Deactive Employee");
                    refresh();
                    return;
                }
                _status.FAIL("Deactive Employee");
            }
            catch (Exception ex)
            {
                AbortServiceClient();
                _status.ERROR(ex.Message);
            }
        }

        private void btnGetAll_Click(object sender, EventArgs e)
        {
            try
            {
                _status.STATUS("Loading List All Employee..");
                List<vEmployeeSubDetail> listEmployee = _employee.EmployeesGet(true);
                grdListEmp.DataSource = new BindingSource {DataSource = listEmployee};
                _status.STATUS("Load List All Employee Done!");
            }
            catch (Exception ex)
            {
                _status.ERROR(ex.Message);
            }
        }

        private void ptbEmpImage_Click(object sender, EventArgs e)
        {
            try
            {
                var ofd = new OpenFileDialog {Filter = "JPG file|*.jpg|JPEG file|*.jpeg"};
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    Image img = _imageTool.ResizeImage(Image.FromFile(ofd.FileName));
                    ptbEmpImage.Image = img;
                }
            }
            catch (Exception ex)
            {
                _status.ERROR(ex.Message);
            }
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            try
            {
                List<vEmployeeSubDetail> listEmployee = _employee.EmployeesGetByName(txtSearch.Text);
                grdListEmp.DataSource = new BindingSource {DataSource = listEmployee};
            }
            catch (Exception ex)
            {
                _status.ERROR(ex.Message);
            }
        }

        private void grdListEmp_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.RowIndex < 0) return;
                string employeeID = grdListEmp.Rows[e.RowIndex].Cells["EmployeeID"].Value.ToString();
                Employee employee = _employee.EmployeeGetById(int.Parse(employeeID));

                txtId.Text = employee.EmployeeID.ToString();
                txtName.Text = employee.EmployeeName;
                rdbMale.Checked = employee.EmployeeSex;
                dtpBirthday.Value = employee.EmployeeBirthday;
                cbxPosition.SelectedItem = employee.EmployeePosition;
                txtPhone.Text = employee.EmployeePhone;
                txtEmail.Text = employee.EmployeeEmail;
                txtAddress.Text = employee.EmployeeAddress;
                txtCity.Text = employee.EmployeeCity;
                txtCountry.Text = employee.EmployeeCountry;
                cbxJobTitle.SelectedItem = employee.EmployeeJobTitle;
                txtPassword.Text = employee.EmployeePassword;
                txtUserName.Text = employee.EmployeeAccount;
                try
                {
                    ptbEmpImage.Image = _imageTool.ByteToImage(employee.EmployeeImage);
                }
                catch (Exception ex)
                { 
                
                }

                foreach (TextBox textBox in _ctrl)
                {
                    textBox.Enabled = true;
                }
                cbxJobTitle.Enabled = true;
                cbxPosition.Enabled = true;
                dtpBirthday.Enabled = true;
                btnUpdate.Enabled = true;
                btnDeactive.Enabled = true;                
                _status.STATUS(string.Format("Selected employee Id: {0}", employee.EmployeeID));
            }
            catch (Exception ex)
            {
                _status.ERROR(ex.Message);
            }
        }

        private void txtEmail_Leave(object sender, EventArgs e)
        {
            string errorMsg;
            ValidEmailAddress(txtEmail.Text, out errorMsg);
            errorProvider.SetError(txtEmail, errorMsg);
        }

        private void txtPhone_Leave(object sender, EventArgs e)
        {
            string errorMsg;
            ValidPhoneNumber(txtPhone.Text, out errorMsg);
            errorProvider.SetError(txtPhone, errorMsg);
        }

        private void textBox_Leave(object sender, EventArgs e)
        {
            ValidString((TextBox) sender);
        }

        private void frmEmployeeManager_Shown(object sender, EventArgs e)
        {
            _myTimer.Enabled = true;
        }

        private void refreshEmpList(object sender, EventArgs e)
        {
            refresh();
            _myTimer.Stop();
        }

        private void refresh()
        {
            try
            {
                List<vEmployeeSubDetail> listEmployee = _employee.EmployeesGet(false);
                var bs = new BindingSource {DataSource = listEmployee};
                grdListEmp.DataSource = bs;
            }
            catch (Exception ex)
            {
                _status.ERROR(ex.Message);
            }
        }


        private static bool ValidPhoneNumber(string phoneNumber, out string errorMessage)
        {
            string strPhone = phoneNumber;
            var rePhone = new Regex(@"^0+\d{2,3}-\d{3}-\d{4}$");
            if (rePhone.IsMatch(strPhone))
            {
                errorMessage = "";
                return true;
            }
            errorMessage = "Phone number mus be valid format 0xx[x]-xxx-xxxx";
            return false;
        }

        private bool ValidEmailAddress(string emailAddress, out string errorMessage)
        {
            int idxA = emailAddress.IndexOf("@", StringComparison.Ordinal);
            if (idxA > -1)
            {
                if (
                    emailAddress.IndexOf(".", idxA, StringComparison.Ordinal) > idxA)
                {
                    if (_employee.EmployeeEmailCheck(emailAddress))
                    {
                        errorMessage = "";
                        return true;
                    }
                    errorMessage = "Email address is exist";
                    return false;
                }
            }
            errorMessage = "e-mail address must be valid e-mail address format. For example 'someone@example.com' ";
            return false;
        }

        private bool ValidString(Control textBox)
        {
            if (textBox.Text.Trim() == "")
            {
                errorProvider.SetError(textBox, "Value is required");
                return false;
            }
            errorProvider.SetError(textBox, "");
            return true;
        }

        private bool ValidForm()
        {
            string err;
            ValidPhoneNumber(txtPhone.Text, out err);
            ValidEmailAddress(txtEmail.Text, out err);
            if (ValidString(txtName) && ValidString(txtAddress) && ValidString(txtCity) && ValidString(txtCountry))
            {
                if (ValidPhoneNumber(txtPhone.Text, out err) && ValidEmailAddress(txtEmail.Text, out err))
                {
                    return true;
                }
            }
            return false;
        }

        private void frmEmployeeManager_FormClosed(object sender, FormClosedEventArgs e)
        {
            _parent.Dispose();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void logoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var t = new Thread(ThreadProc);
            t.Start();
            Close();
        }

        public void ThreadProc()
        {
            Application.Run(new frmMain(_parent.UName, ""));
        }

        private void hotelManagerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (_parent.Hotel == null)
            {
                _parent.Hotel = new frmHotelManager(_parent);
                _parent.Hotel.Show();
                Hide();
            }
            else
            {
                _parent.Hotel.Show();
                Hide();
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var about = new frmAbout();
            about.ShowDialog(this);
        }

        private void userInfoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var userinf = new frmUserInfo(_parent);
            userinf.ShowDialog(this);
        }
    }
}